﻿using System;
using System.IO;

namespace EditoneLib.Streams
{
    internal class OffsetStream : ReadonlyStream
    {
        private readonly long? _maxLength;
        private readonly long _offset;
        private readonly Stream _sourceStream;

        public OffsetStream(Stream sourceStream, long offset, long? maxLength = null)
        {
            if (!sourceStream.CanSeek)
                throw new ArgumentException("Source stream must be seekable.");

            _sourceStream = sourceStream;
            _offset = offset;
            _maxLength = maxLength;
        }

        public override long Length
        {
            get
            {
                return _maxLength.HasValue
                    ? Math.Min(_sourceStream.Length - _offset, _maxLength.Value)
                    : _sourceStream.Length - _offset;
            }
        }

        public override long Position
        {
            get { return _sourceStream.Position - _offset; }
            set { Seek(value, SeekOrigin.Begin); }
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            lock (_sourceStream)
            {
                return _sourceStream.Read(buffer, offset, count);
            }
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            lock (_sourceStream)
            {
                return _sourceStream.Seek(offset + _offset, origin);
            }
        }
    }
}